/*
 * PropertyHelper.h
 *
 *  Created on: 2011-3-26
 *      Author: wangchao
 */

#ifndef PROPERTYHELPER_H_
#define PROPERTYHELPER_H_
#include <e32def.h>
template< typename ValueType >
class ReadProperty
{
public:
    ReadProperty( ) :
        _value( ValueType( ) )
    {

    }
public:
    operator ValueType( )
    {
        return _value;
    }

protected:
    ValueType _value;
};

template< typename ValueType >
class Property
{
private:
    const Property< ValueType >& operator=( const Property< ValueType >& )
    {
    }
    Property( Property< ValueType >& )
    {
    }
public:
    Property( ) :
        _handle( NULL ), _observer( NULL )
    {

    }
public:
    operator ValueType( ) const
    {
        return _value;
    }

protected:
    ValueType _value;
public:
    Property< ValueType >& operator =( const ValueType& value )
    {
        Set( value );
        return *this;
    }

    /*void operator =( const ValueType& value )
     {
     _value = value;

     if( _observer && _handle )
     {
     ( *_handle )( _observer, _value );
     }

     }*/

    void Set( const ValueType& value )
    {
        if( _value != value )
        {
            _value = value;

            if( _observer && _handle )
            {
                ( *_handle )( _observer, _value );
            }
        }
    }

    ValueType operator ->( )
    {
        return _value;
    }
    ValueType& operator&( )
    {
        return _value;
    }

    //operator bool( ) const
    //{
    //    return ( bool )_value;
    //}

public:
    //typedef void (Observer::*ValueChanged)( ValueType value );
    typedef void (*ValueChanged)( void* object_ptr, ValueType );
protected:
    ValueChanged _handle;
    void* _observer;
public:
    template< class Observer, void(Observer::*ValueChangedHandle)( ValueType ) >
    void Register( Observer* observer )
    {
        _observer = observer;
        _handle = &method_stub< Observer, ValueChangedHandle > ;
    }
private:
    template< class Observer, void(Observer::*handle)( ValueType ) >
    static void method_stub( void* object_ptr, ValueType v )
    {
        Observer* p = static_cast< Observer* > ( object_ptr );
        return ( p->*handle )( v ); // #2
    }
};

#endif /* PROPERTYHELPER_H_ */
